//
//  FotoMare.m
//  iDent
//
//  Created by Marius Corega on 7/15/09.
//  Copyright 2009 Marius Corega. All rights reserved.
//

#import "FotoMare.h"


@implementation FotoMare

-(float) exposureValue
{
	return exposureValue;
}

-(float) zoomValue
{
	return zoomValue;
}

-(float) brightnessValue
{
	return brightnessValue;
}

-(float) contrastValue
{
	return contrastValue;
}

-(float) saturationValue
{
	return saturationValue;
}

-(float) rotationValue
{
	return rotationValue;
}

-(CGPoint) origin
{
	return origin;
}

-(int) tipFoto
{
	return [tipFotoPB indexOfSelectedItem];
}

-(NSString*) descriereFoto
{
	return [descriereFotoTB stringValue];
}

-(NSString*) dataFoto
{
	return [dataFotoDP stringValue];
}


-(void) setExposureValue:(float) val
{
	exposureValue = val;
	[exposureSlider setFloatValue:val];
}

-(void) setZoomValue:(float) val
{
	zoomValue = val;
	[zoomSlider setFloatValue:val];
}

-(void) setSaturationValue:(float) val
{
	saturationValue = val;
	[saturationSlider setFloatValue:val];
}

-(void) setRotationValue:(float) val
{
	rotationValue = val;
	[rotationSlider setFloatValue:val];
}

-(void) setBrightnessValue:(float) val
{
	brightnessValue = val;
	[brightnessSlider setFloatValue:val];
}

-(void) setContrastValue:(float) val
{
	contrastValue = val;
	[contrastSlider setFloatValue:val];
}

-(void) setFlipHorizontal:(bool)val
{
	flipHorizontal = val;
}

-(void) setFlipVertical:(bool)val
{
	flipVertical = val;
}

-(void) setOriginX:(int) val
{
	origin.x = val;
}

-(void) setOriginY:(int) val;
{
	origin.y = val;
}

-(void) setTipFoto:(int) val
{
	[tipFotoPB selectItemAtIndex:val];
}

-(void) exposureChanged:(id)sender
{
	
	exposureValue = [sender floatValue];
	
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[exposureSlider stringValue] forKey:@"exposure"];
	
    [self setNeedsDisplay: YES];

}

-(void) setDescriereFoto:(NSString*) str
{
	[descriereFotoTB setStringValue:str];
}

-(void) setDataFoto:(NSString*) str
{
	[dataFotoDP setStringValue:str];
}


-(IBAction) zoomChanged:(id)sender
{
	zoomValue = [sender floatValue];
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[zoomSlider stringValue] forKey:@"zoom"];

	[self setNeedsDisplay:YES];
}

-(IBAction) brightnessChanged:(id)sender
{
	brightnessValue = [sender floatValue];
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[brightnessSlider stringValue] forKey:@"brightness"];
	
	[self setNeedsDisplay:YES];	
}

-(IBAction) contrastChanged:(id)sender
{
	contrastValue = [sender floatValue];
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[contrastSlider stringValue] forKey:@"contrast"];
	
	[self setNeedsDisplay:YES];	
}

-(IBAction) saturationChanged:(id)sender
{
	saturationValue = [sender floatValue];
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[saturationSlider stringValue] forKey:@"saturation"];
	
	[self setNeedsDisplay:YES];	
}

-(IBAction) rotationChanged:(id)sender
{
	rotationValue = [sender floatValue];
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	[selPoza setValue:[rotationSlider stringValue] forKey:@"rotation"];
	
	[self setNeedsDisplay:YES];	
}

-(IBAction) flipH:(id)sender
{
	flipHorizontal = !flipHorizontal;
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];
	NSNumber *n = [NSNumber numberWithBool:flipHorizontal];
	[selPoza setValue:[n stringValue] forKey:@"fliph"];
	
	
	[self setNeedsDisplay:YES];
}

-(IBAction) flipV:(id)sender;
{
	flipVertical = !flipVertical;
	NSDictionary *selPoza = [[pozeAC selectedObjects] objectAtIndex:0];	
	NSNumber *n = [NSNumber numberWithBool:flipVertical];
	[selPoza setValue:[n stringValue] forKey:@"flipv"];
	
	[self setNeedsDisplay:YES];
}

-(IBAction) showToolWindow:(id)sender
{
	if([toolWindow isVisible]) [toolWindow orderOut:self];
	else [toolWindow orderFront:self];
}

- (void)awakeFromNib 
{
    /*
	 **  Enabling QuartzGL for this window greatly improves
	 **  rendering preformance when Core Image drawing goes
	 **  to a Core Graphics context.
	 */
    [[self window] setPreferredBackingLocation:	 NSWindowBackingLocationVideoMemory];
/*	zoomValue = 1.0;
	brightnessValue = 0.0;
	contrastValue = 1.0;
	saturationValue = 1.0;
	rotationValue = 0.0f;
 */
	flipVertical = flipHorizontal = NO;
}

-(void) setImageData:(NSData*) img
{
	//[img retain];
	//image = [CIImage imageWithData: img];
	if (imagedata != nil) {[imagedata release]; imagedata = nil;};
	if (image != nil) {[image release]; image = nil;}
	
	
	imagedata = img;
	[imagedata retain];
	
	image = [[[CIImage alloc] initWithData:img] autorelease];

	[image retain];

	[self setNeedsDisplay:YES];
}

-(void) setImage:(NSImage*) img
{
	if(imagedata != nil) [imagedata release];
	imagedata = [NSData dataWithData:[img TIFFRepresentation]];
	[imagedata retain];
	
	[self setNeedsDisplay:YES];
	
}

-(void) setNoImage
{
	if (imagedata != nil) {[imagedata release]; imagedata = nil;}
	if (image != nil) {[image release]; image = nil;}
	
	[self setNeedsDisplay:YES];

}

- (void) centerOriginInRect:(NSRect) aRect  { [self translateOriginToPoint:NSMakePoint(NSMidX(aRect), NSMidY(aRect))];}

- (void) centerOriginInBounds  { [self centerOriginInRect:[self bounds]];  }
- (void) centerOriginInFrame  { [self centerOriginInRect:[self convertRect:[self frame] fromView:[self superview]]];  }


- (void)drawRect: (NSRect)rect
{
    CIContext *context = [[NSGraphicsContext currentContext] CIContext];
    CGRect     cg = CGRectMake(NSMinX(rect), NSMinY(rect),
							   NSWidth(rect), NSHeight(rect));
	
	//[self centerOriginInBounds];
    
	
	//if(imagedata != nil)
	{
			
			
			/*
			 **  First time around, we load the image from disk and
			 **  instantiate the filter object. Holding on to the image
			 **  and the filter does improve performance as it will
			 **  avoid memory allocations and I/O on subsequent draw
			 **  calls.
			 */
	
		if([[pozeAC selectedObjects] count]>0)
		{
			NSDictionary*  imageDict = [[pozeAC selectedObjects] objectAtIndex:0];
			
			filter   = [CIFilter filterWithName: @"CIExposureAdjust"
								  keysAndValues: @"inputImage", image, nil];
			
			[filter setValue: [NSNumber numberWithFloat: [[imageDict objectForKey:@"exposure"] floatValue]]
					  forKey: @"inputEV"];
			
			filter   = [CIFilter filterWithName: @"CIColorControls"
								  keysAndValues: @"inputImage", [filter valueForKey:@"outputImage"], nil];
			
			[filter setValue: [NSNumber numberWithFloat: [[imageDict objectForKey:@"brightnes"] floatValue]]
					  forKey: @"inputBrightness"];
			[filter setValue: [NSNumber numberWithFloat: [[imageDict objectForKey:@"contrast"] floatValue]]
					  forKey: @"inputContrast"];
			[filter setValue: [NSNumber numberWithFloat: [[imageDict objectForKey:@"saturation"] floatValue]]
					  forKey: @"inputSaturation"];
			
			
			if(context != nil)
			{
				CIFilter *f = [CIFilter filterWithName:@"CIAffineTransform"];
				NSAffineTransform *t = [NSAffineTransform transform];
				
				//	if(res2 != nil) [res2 release];
				//	if(res != nil) [res release];
				
				
				CIImage *res = [filter valueForKey:@"outputImage"];
				
				NSRect myBounds = [self bounds];
				NSPoint centerPoint = NSMakePoint(myBounds.size.width/2, 
												  myBounds.size.height/2);
				
				
				[t translateXBy:[[imageDict objectForKey:@"originex"] floatValue] yBy:[[imageDict objectForKey:@"originey"] floatValue]];
				[t translateXBy:centerPoint.x yBy:centerPoint.y];
				//[t rotateByDegrees:rotationValue];
				[t rotateByDegrees:[[imageDict objectForKey:@"rotation"] floatValue]];
				
				[t translateXBy:-centerPoint.x yBy:-centerPoint.y];
				
				
				
				if ([[imageDict objectForKey:@"flipv"] boolValue])
				{
					[t scaleXBy: 1.0 yBy:-1.0];
					[t translateXBy:0 yBy:-myBounds.size.height];
				}
				
				if ([[imageDict objectForKey:@"fliph"] boolValue])
				{
					[t scaleXBy: -1.0 yBy:1.0];
					[t translateXBy:-myBounds.size.width yBy:0];
				}
				[t translateXBy:centerPoint.x yBy:centerPoint.y];
				
				[t scaleBy:[[imageDict objectForKey:@"zoom"] floatValue]];
				[t translateXBy:-centerPoint.x yBy:-centerPoint.y];
				
				//[t concat];
				
				[f setValue:t forKey:@"inputTransform"];
				[f setValue:res forKey:@"inputImage"];
				CIImage *res2 = [f valueForKey:@"outputImage"];
				
				CGPoint x;
				x.x = -200;
				x.y = -200;
				
				//[self centerOriginInFrame];
				
				[context drawImage:res2
				 //	inRect:cg fromRect:cg];
						   atPoint: cg.origin  fromRect: cg];
				//   atPoint: x  fromRect: cg];
				//[res2 autorelease];
				//[res autorelease];
				//[f autorelease];
			}
		}
	}
}

- (void)mouseDown:(NSEvent *)theEvent
{
	//[super mouseDown:theEvent];
	
	NSPoint loc = [theEvent locationInWindow];
	NSPoint local_point = [self convertPoint:loc fromView:nil];
	
	mouseinit.x = local_point.x; mouseinit.y = local_point.y;
}

- (void)mouseDragged:(NSEvent *)theEvent
{
	//[super mouseDragged:theEvent];
	if([[pozeAC selectedObjects] count]>0)
	{
		NSMutableDictionary*  imageDict = [[pozeAC selectedObjects] objectAtIndex:0];
		
		NSPoint loc = [theEvent locationInWindow];
		NSPoint local_point = [self convertPoint:loc fromView:nil];
		origin.x = [[imageDict objectForKey:@"originex"] intValue];
		origin.y = [[imageDict objectForKey:@"originey"] intValue];
		origin.x += local_point.x - mouseinit.x; origin.y += local_point.y - mouseinit.y;
		[imageDict setObject:[[NSNumber numberWithInt:origin.x] stringValue] forKey:@"originex"];
		[imageDict setObject:[[NSNumber numberWithInt:origin.y] stringValue] forKey:@"originey"];
		
		mouseinit.x = local_point.x;
		mouseinit.y = local_point.y;
		[self setNeedsDisplay:YES];
		}
		
}

- (void)scrollWheel:(NSEvent *)theEvent
{
	NSNumber *z = [NSNumber numberWithFloat: zoomValue + [theEvent deltaY]/10];
	if([zoomSlider floatValue] >=0){ [self zoomChanged:z]; [zoomSlider setFloatValue:[z floatValue]];}
	[self setNeedsDisplay:YES];
}

-(IBAction)redrawImage:(id)sender
{
	[self setNeedsDisplay:YES];
}

-(void)dealloc
{
	
	[image release];
	[imagedata release];
	[filter release];
	
	[super dealloc];
}

@end
